import { defineStore } from 'pinia';
import { isValidJsonString } from '@/common/js/common-helper';
import { getToken } from '@/utils/auth';

// WebSocket 地址
const wsUrl = import.meta.env.VITE_WEBSOCKET_URL + '/websocket';

const useStompJsStore = defineStore('StompJs', {
  state: () => ({
    _client: null,
    status: 'disconnected',
    message: [],
    reconnectInterval: 120000, // 自动重连的间隔（毫秒）
    pingInterval: 30000, // 心跳间隔（毫秒）
    timer: null,
    flickerShow: false,
    route: '',
    onMessageCallback: null, // 用于存储 `onMessage`
  }),

  getters: {
    stompClient: (state) => state._client,
    getMessage: (state) => state.message,
    getStatus: (state) => state.status,
    getRoute: (state) => state.route,
    getFlickerShow: (state) => state.flickerShow,
  },

  actions: {
    // 激活 WebSocket 连接
    setActivate(options) {
      if (this._client) {
        console.warn('WebSocket 已经连接');

        return;
      }

      // 存储 `onMessage` 以便重连时使用
      if (options.onMessage) {
        this.onMessageCallback = options.onMessage;
      }

      this._client = new WebSocket(`${wsUrl}?X-Client-Type=web&Authorization=${getToken() ? `${getToken()}` : ''}`);
      // this._client = new WebSocket(`${wsUrl}?X-Client-Type=web`);
      this.status = 'connecting';

      // 连接打开时
      this._client.onopen = () => {
        console.info('WebSocket 连接开启');
        this.status = 'connected';

        // 使用箭头函数调用 sendMessage，确保 this 指向 store
        this.sendMessage(['连接成功']);

        if (this.timer) {
          clearInterval(this.timer);
          this.timer = null;
        }

        // 启动心跳机制
        this.startHeartbeat();
      };

      // 监听消息
      this._client.onmessage = (event) => {
        try {
          const data = isValidJsonString(event.data) ? JSON.parse(event.data) : event.data;

          console.info('WebSocket 接收消息:', data);

          if (this.onMessageCallback) {
            this.onMessageCallback(data);
          }
        } catch (error) {
          console.error('消息解析失败:', error);
        }
      };

      // 监听错误
      this._client.onerror = (event) => {
        console.error('WebSocket 错误:', event);
        this.status = 'error';
        this.reconnect(); // 连接错误时，尝试重连
      };

      // 监听关闭
      this._client.onclose = () => {
        console.warn('WebSocket 连接关闭');
        this.status = 'disconnected';
        this._client = null;
        this.reconnect(); // 连接关闭时，尝试重连
      };
    },

    // 发送心跳包
    startHeartbeat() {
      this.lastPongTime = Date.now();
      this.timer = setInterval(() => {
        if (this._client && this._client.readyState === WebSocket.OPEN) {
          this.sendMessage(['ping']); // 发送 ping
        }

        if (this.lastPongTime && Date.now() - this.lastPongTime > this.pongTimeout) {
          console.warn('心跳超时，尝试重连...');
          this.setDeActivate(); // 超时则关闭连接
          this.reconnect(); // 尝试重连
        }
      }, this.pingInterval); // 每 pingInterval 毫秒发送一次心跳
    },

    // 自动重连
    reconnect() {
      if (this.status === 'disconnected' || this.status === 'error') {
        console.info('尝试重连 WebSocket...');
        setTimeout(() => {
          this.setActivate({
            onMessage: this.onMessageCallback, // 继续使用 `App.vue` 传入的 `onMessage`
          });
        }, 10);
      }
    },

    // 发送消息
    sendMessage(data) {
      if (!this._client || this._client.readyState !== WebSocket.OPEN) {
        console.warn('WebSocket 未连接，消息发送失败');

        return;
      }

      this._client.send(JSON.stringify(data));
    },

    // 关闭 WebSocket 连接
    setDeActivate() {
      if (this._client) {
        clearInterval(this.timer);
        this.timer = null;

        this._client.close();
        this._client = null;
        this.status = 'disconnected';
      }
    },

    setMessage(message) {
      this.message = message;
    },
  },
});

export default useStompJsStore;
